#include "mainwindow.h"
#include "ui_mainwindow.h"

#include "TranslatorX.h"
#include "TranslatorY.h"
#include "TranslatorZ.h"

#include "RotatorX.h"
#include "RotatorY.h"
#include "RotatorZ.h"

enum Tranformations
{
	TRANSLATE_X,
	TRANSLATE_Y,
	TRANSLATE_Z,

	ROTATE_X,
	ROTATE_Y,
	ROTATE_Z,
};

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);

	QGLFormat fmt;
	fmt.setAlpha(true);
	m_glWidget = new MyGLWidget(fmt, this, *this);

	ui->centralWidget->layout()->addWidget(m_glWidget);
	
	connect(ui->xSB, SIGNAL(valueChanged(double)), this, SLOT(on_zSB_valueChanged(double)));
	connect(ui->ySB, SIGNAL(valueChanged(double)), this, SLOT(on_zSB_valueChanged(double)));

	connect(ui->addMatrix, SIGNAL(clicked()), this, SLOT(addButtonClicked()));

	ui->matrixOps->addItem("Translate X", QVariant(TRANSLATE_X));
	ui->matrixOps->addItem("Translate Y", QVariant(TRANSLATE_Y));
	ui->matrixOps->addItem("Translate Z", QVariant(TRANSLATE_Z));

	ui->matrixOps->addItem("Rotate X", QVariant(ROTATE_X));
	ui->matrixOps->addItem("Rotate Y", QVariant(ROTATE_Y));
	ui->matrixOps->addItem("Rotate Z", QVariant(ROTATE_Z));

	m_mtxStackLayout = new QVBoxLayout();
	ui->matrixStackFrame->setLayout(m_mtxStackLayout);

	m_mtxStackLayout->addStretch();
}

MainWindow::~MainWindow()
{
	delete m_glWidget;
    delete ui;
}

void MainWindow::on_zSB_valueChanged(double )
{
    m_glWidget->setVector(ui->xSB->value(), ui->ySB->value(), ui->zSB->value());
	m_glWidget->updateGL();
}

void MainWindow::addButtonClicked()
{
	WidgetWithMatrix *newW = NULL;

	switch ( ui->matrixOps->itemData(ui->matrixOps->currentIndex()).toInt() )
	{
	case TRANSLATE_X:
		newW = new TranslatorX(ui->matrixStackFrame, m_glWidget->getMatrixStack());
		break;

	case TRANSLATE_Y:
		newW = new TranslatorY(ui->matrixStackFrame, m_glWidget->getMatrixStack());
		break;

	case TRANSLATE_Z:
		newW = new TranslatorZ(ui->matrixStackFrame, m_glWidget->getMatrixStack());
		break;

	case ROTATE_X:
		newW = new RotatorX(ui->matrixStackFrame, m_glWidget->getMatrixStack());
		break;

	case ROTATE_Y:
		newW = new RotatorY(ui->matrixStackFrame, m_glWidget->getMatrixStack());
		break;

	case ROTATE_Z:
		newW = new RotatorZ(ui->matrixStackFrame, m_glWidget->getMatrixStack());
		break;

	}

	if ( newW == NULL )
	{
		return;
	}

	//m_mtxStackLayout = static_cast<QVBoxLayout *>(ui->matrixStackFrame->layout());

	m_mtxStackLayout->insertWidget(m_widgetList.size(), newW);
//	m_mtxStackLayout->addWidget(newW);
	m_widgetList.push_back(newW);
}

void MainWindow::matrixMovedUp(int id)
{
	WidgetWithMatrix *widget = findWidgetWithMatrixByMatrixId(id);

	if ( id == NULL )
	{
		return;
	}

	int index = m_mtxStackLayout->indexOf(widget);

	if ( index <= 0 )
	{
		return;
	}

	m_mtxStackLayout->removeWidget(widget);
	m_mtxStackLayout->insertWidget(index - 1, widget);
}

void MainWindow::matrixMovedDown(int id)
{
	WidgetWithMatrix *widget = findWidgetWithMatrixByMatrixId(id);

	if ( id == NULL )
	{
		return;
	}

	int index = m_mtxStackLayout->indexOf(widget);

	if ( index < 0 || index >= m_widgetList.size() - 1 )
	{
		return;
	}

	m_mtxStackLayout->removeWidget(widget);
	m_mtxStackLayout->insertWidget(index + 1, widget);
}

WidgetWithMatrix *MainWindow::findWidgetWithMatrixByMatrixId(int id)
{
	for ( WidgetsWithMatrixList::const_iterator i = m_widgetList.begin(); i != m_widgetList.end(); ++i )
	{
		if ( (*i)->getMatrixId() == id )
		{
			return *i;
		}
	}

	return NULL;
}

